<?php

declare(strict_types=1);

namespace app\core;

use app\core\Log;
use Swoole\Database\PDOConfig;
use Swoole\Database\PDOPool;
use Exception;
use PDOException;
use Swoole\Coroutine;

class Db
{

    public $pool = null;
    public $pdo = null;
    private $config = [
        'host' => '127.0.0.1',
        'port' => 3306,
        'database' => '',
        'username' => '',
        'password' => '',
        'charset' => '',
        'unixSocket' => null,
        'options' =>  [],
        'size' => 320,
    ];
    
    private static $instance;
    public function __construct()
    {
        try {


            if (empty($this->pool)) {
                $config = config('database');

                $this->config = array_replace_recursive($this->config, $config);
                $this->pool = new PDOPool((new PDOConfig)
                        ->withHost($this->config['host'])
                        ->withPort($this->config['port'])
                        ->withDbName($this->config['database'])
                        ->withCharset($this->config['charset'])
                        ->withUsername($this->config['username'])
                        ->withPassword($this->config['password'])
                        ->withUnixSocket($this->config['unixSocket'])
                        ->withOptions($this->config['options']),
                    $this->config['size']
                );
            }
        } catch (PDOException $e) {
            $this->pool->put(null);
            throw new Exception($e);
          
        }
    }
    public static function getInstance()
    {

        if (empty(self::$instance)) {
            self::$instance = new static();
        }

        return self::$instance;
    }
    public function getConnection()
    {

        return $this->pool->get();
    }
    public function close($connection = null)
    {
        // Coroutine::defer(function()use($connection){
      
        //     $this->pool->put($connection);
        // });
        $this->pool->put($connection);
    }
   
    public function test()
    {
        $pdo = $this->getConnection();
        $pdo->beginTransaction();

        $statement = $pdo->prepare('SELECT * FROM order_users limit 1');
        $statement->execute();
        $result = $statement->fetchAll();
        // print_r($result);
        $pdo->commit();
        $this->close($pdo);
    }
}
